import java.io.*;
import java.net.*;

import ro.pub.cs.dfsa.client.connection.AbstractClientConnection;
import ro.pub.cs.dfsa.client.framework.FrameList;
import ro.pub.cs.dfsa.client.framework.FrameFile;
import ro.pub.cs.dfsa.client.framework.Request;
import ro.pub.cs.dfsa.client.framework.RequestType;
import ro.pub.cs.dfsa.server.connection.AbstractServerConnection;

public class RequestProcessor extends Thread{
	
	//private Socket socket;
	private int id;
	private AbstractClientConnection connection;
	
	public RequestProcessor(int id, AbstractClientConnection connection) {
//		this.socket = socket;
		this.id = id;
		this.connection = connection;
	}

	public void run(){
		try{
//			ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
//			ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
			while (true){
				Request req;
				
				try {
					req = (Request) connection.readObject(Request.class);
				}
				catch (Exception e) {
					break;
				}
				
				if (req.type == RequestType.LIST){
					File folder = new File(ServerConstants.DIRECTORY_PATH + this.id);
				    File[] listOfFiles = folder.listFiles();
				    
				    System.out.println(listOfFiles.length);
				    int nrChunks = listOfFiles.length / ServerConstants.MAX_FILES_PER_REQUEST;
				    if (listOfFiles.length % ServerConstants.MAX_FILES_PER_REQUEST != 0)
				    	nrChunks++;
				    
				    // daca nu sunt fisiere de listat trimit un frame gol
				    if (nrChunks == 0) {
				    	FrameList frame = new FrameList();
				    	frame.lastFrame = true;
				    	connection.writeObject(frame);
				    }
				    
				    for (int i = 0; i < nrChunks; i++) {
				    	FrameList frame = new FrameList();
				    	frame.content = new String[ServerConstants.MAX_FILES_PER_REQUEST];
				    	
				    	int start = i * ServerConstants.MAX_FILES_PER_REQUEST;
				    	int stop;
				    	int count = 0;
				    	
				    	if (i < nrChunks - 1) {
				    		stop = start + ServerConstants.MAX_FILES_PER_REQUEST - 1;
				    		frame.lastFrame = false;
				    	}
				    	else {
				    		stop = listOfFiles.length - 1;
				    		frame.lastFrame = true;
				    	}
				    	
				    	for (int j = start; j <= stop; j++) {
				    		System.out.println(j + " " + listOfFiles[j].getName());
				    		frame.content[count++] = listOfFiles[j].getName();
				    	}
				    	System.out.println();
				    	
				    	connection.writeObject(frame);
				    }   
				    
				} else if (req.type == RequestType.UPLOAD){
					String completeFileName = ServerConstants.DIRECTORY_PATH + this.id +
						File.separator + req.name;

					FileOutputStream fos = new FileOutputStream(completeFileName);

					FrameFile frame;
					do {
						frame = connection.readObject(FrameFile.class);
						fos.write(frame.content);
					} while (!frame.lastFrame);

					fos.close();
				} else if (req.type == RequestType.DOWNLOAD){
					String completeFileName = ServerConstants.DIRECTORY_PATH + this.id + 
						File.separator + req.name;
					FileInputStream fis = new FileInputStream(completeFileName);
					
					int nrBytes = 0;
					while (true) {
						FrameFile frame = new FrameFile();
						frame.content = new byte[ServerConstants.MAX_BYTES_PER_FILE_FRAME];
						
						nrBytes = fis.read(frame.content);
						if (nrBytes < ServerConstants.MAX_BYTES_PER_FILE_FRAME) {
							frame.lastFrame = true;
							connection.writeObject(frame);
							break;
						}
						else {
							frame.lastFrame = false;
							connection.writeObject(frame);
						}
					}
				} else if (req.type == RequestType.DELETE){
					String fileName = req.name;
					System.out.println("O sa sterg " + fileName);
					
					File folder = new File(ServerConstants.DIRECTORY_PATH + this.id);
					File[] listOfFiles = folder.listFiles();
					
					try {
						for (File file : listOfFiles){
							if (file.getName().equals(fileName))
								if (!file.delete())
									throw new FileNotFoundException("Failed to delete file " + file);
						}
					} catch (Exception e) {}
				}
			}
			connection.close();
		} catch (Exception e){
			System.err.println("SocketConnectorReceiveTask-" + this.hashCode() + " exception: " + e);
			e.printStackTrace();
		}
	}

}
